use sqlite_wasm_rs::{sqlite3, sqlite3_step, sqlite3_stmt, SQLITE_ROW};
use crate::db::db::print_error;
use crate::db::util::db_get_int64;

pub unsafe fn row_wrap<T>(db: *mut sqlite3, label: &'static str, stmt: *mut sqlite3_stmt, wrap: Box<dyn Fn(*mut sqlite3_stmt) -> T>) -> Vec<T> {
    let mut result = Vec::new();
    loop {
        let ret = sqlite3_step(stmt);
        if ret == SQLITE_ROW {
            let data = wrap(stmt);
            result.push(data);
        } else {
            print_error(db, ret, label);
            break;
        }
    }
    
    result
}

pub unsafe fn get_one<T>(stmt: *mut sqlite3_stmt, wrap: Box<dyn Fn(*mut sqlite3_stmt) -> T>) -> Option<T> {
    if sqlite3_step(stmt) == SQLITE_ROW {
        let data = wrap(stmt);
        return Some(data)
    }
    None
}

pub unsafe fn get_many<T>(stmt: *mut sqlite3_stmt, wrap: Box<dyn Fn(*mut sqlite3_stmt) -> T>) -> Vec<T> {
    let mut result = Vec::new();
    while sqlite3_step(stmt) == SQLITE_ROW {
        let data = wrap(stmt);
        result.push(data);
    }
    result
}

pub unsafe fn query_count(stmt: *mut sqlite3_stmt) -> usize {
    if sqlite3_step(stmt) == SQLITE_ROW {
        let total = db_get_int64(stmt, 0);
        return total as usize
    }
    0
}